#pragma once

#include <iostream>
#include <queue>
#include <vector>
#include <pthread.h>
#include <functional>
#include "Log.hpp"
#include "Thread.hpp"
#include "LockGuard.hpp"

using namespace ThreadTest;

#define default_num 5

template <typename T, typename ThreadDate>
class ThreadPool
{
public:
    ThreadPool(int thread_num = default_num) :_thread_num(thread_num), _waitnum(0), _isrunning(false)
    {
        pthread_mutex_init(&_mutex, nullptr);
        pthread_cond_init(&_cond, nullptr);
        //构建指定数量的线程
        for (int i = 0; i < _thread_num; i++)
        {
            std::string name = "thread-" + std::to_string(i + 1);
            ThreadDate td;
            // _threads.emplace_back(std::bind(&ThreadPool::HandlerTask, this, std::placeholders::_1), name);
            _threads.emplace_back(std::bind(&ThreadPool<T, ThreadDate>::ThreadRun, this, std::placeholders::_1, std::placeholders::_2), name, td);
        }
    }

    //上锁
    void LockQueue()
    {
        pthread_mutex_lock(&_mutex);
    }

    //解锁
    void UnlockQueue()
    {
        pthread_mutex_unlock(&_mutex);
    }

    //线程等待
    void ThreadSleep()
    {
        pthread_cond_wait(&_cond, &_mutex);
    }

    //线程唤醒，唤醒一个线程
    void ThreadWakeUp()
    {
        pthread_cond_signal(&_cond);
    }

    //唤醒所有线程
    void ThreadWakeUpAll()
    {
        pthread_cond_broadcast(&_cond);
    }

    //启动线程池
    bool Start()
    {
        for (auto &thread : _threads)
        {
            if (!thread.Start()) return false;
            std::cout << "thread is running ..." << std::endl;
        }
        _isrunning = true;
        return true;
    }

    //回收所有线程
    bool WaitALLThread()
    {
        for (auto &thread : _threads)
        {
            if (!thread.Join()) return false;
            std::cout << thread.name() << " has finished!" << std::endl;
        }
        _isrunning = false;
        return true;
    }

    //线程启动
    void ThreadRun(ThreadDate& td, std::string thread_name)
    {
        std::cout << thread_name << " is running" << std::endl;
    }
    // //回收指定线程
    // bool WaitThread(Thread<ThreadDate> &thread)
    // {
    //     if (!thread.Join()) return false;
    //     else return true;
    // }
private:
    int _thread_num; //线程数目
    std::queue<T> _task_queue; //任务队列
    std::vector<Thread<ThreadDate>> _threads; //管理线程
    pthread_mutex_t _mutex;
    pthread_cond_t _cond; 

    int _waitnum; //等待的线程数量
    bool _isrunning; //线程池启动情况
};

